# app/map_tab.py
import io, json
from pathlib import Path
import streamlit as st
from PIL import Image
from folium.plugins import MarkerCluster
import folium
from streamlit_folium import st_folium

from .yolo_demo import Detector, draw_boxes
from .geo import read_gps_from_image, feature_point, feature_collection

ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "outputs"
OUT.mkdir(parents=True, exist_ok=True)

def render():
    st.header("🗺️ 定位与地图（EXIF → 点位 → 地图）")
    st.caption("上传若干图片 → YOLO 占位检测 → 读取 EXIF GPS → 地图聚合 → 导出 GeoJSON")
    with st.sidebar:
        st.subheader("地图参数")
        conf = st.slider("YOLO 置信阈值", 0.05, 0.9, 0.25, 0.05)
        iou = st.slider("NMS IoU", 0.1, 0.9, 0.45, 0.05)
        device = st.selectbox("设备", ["auto", "cpu", "cuda"], index=0)
        weights = st.text_input("权重（可替换为你明天训练的 *.pt）", "yolov8n.pt")

    files = st.file_uploader("选择图片（JPG/PNG，最好含 EXIF GPS）", type=["jpg","jpeg","png"], accept_multiple_files=True)
    if not files:
        st.info("上传 3–10 张样例即可开始。")
        return

    det = Detector(weights=weights, device=None if device=="auto" else device)

    feats = []
    cols = st.columns(2)
    for i, f in enumerate(files):
        raw = f.read()
        pil = Image.open(io.BytesIO(raw)).convert("RGB")
        tmp = OUT / f"tabc_{i}_{f.name}"
        with tmp.open("wb") as w:
            w.write(raw)

        dets = det.predict(tmp, conf=conf, iou=iou)
        vis = draw_boxes(pil, dets)
        with cols[i % 2]:
            st.subheader(f.name)
            st.image(vis, use_container_width=True)
            st.json({"top5": dets[:5], "total": len(dets)})

        lat, lon = read_gps_from_image(tmp)
        if lat and lon:
            feats.append(feature_point(lon, lat, {"file": f.name, "detections": len(dets)}))

    st.markdown("---")
    st.subheader("空间分布地图")
    if feats:
        fc = feature_collection(feats)
        lats = [ft["geometry"]["coordinates"][1] for ft in feats]
        lons = [ft["geometry"]["coordinates"][0] for ft in feats]
        center = [sum(lats)/len(lats), sum(lons)/len(lons)]
        m = folium.Map(location=center, zoom_start=16, control_scale=True)
        cluster = MarkerCluster().add_to(m)
        for ft in feats:
            lon, lat = ft["geometry"]["coordinates"]
            props = ft["properties"]
            popup = folium.Popup(html=f'<b>{props["file"]}</b><br/>检测数：{props["detections"]}', max_width=250)
            folium.Marker([lat, lon], popup=popup).add_to(cluster)
        st_folium(m, width=None, height=500)

        st.download_button("下载 GeoJSON", data=json.dumps(fc, ensure_ascii=False).encode("utf-8"),
                           file_name="detections.geojson", mime="application/geo+json")
    else:
        st.warning("这些图片未包含 EXIF GPS；仍可完成 AI 检测，但无法绘制地图。")
